package wwiii;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.TreeSet;

import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

@PersistenceCapable(detachable = "true")
public class Game {
	public static Key getKey(String id) {
		if (id == null || id.isEmpty()) throw new IllegalArgumentException("gameId is not valid '"+ id +"'");

		return KeyFactory.createKey(Game.class.getSimpleName(), id);
	}

	@PrimaryKey
	@Persistent
	private Key key;
	public Key getKey() { return key; }

	@Persistent
	private String id;
	public String getId() { return id; }

	@Persistent
	private String name;
	public String getName() { return name; }

	@Persistent(defaultFetchGroup = "true", dependent = "true")
	private AreaMap map;
	public AreaMap getMap() { return map; }
	public void setMap(AreaMap map) {
//		if (!state.canAddMap()) { throw new IllegalStateException(); }

		this.map = map;
	}

	@Persistent(defaultFetchGroup = "true", dependent = "true")
	private GameState state;
	public GameState getState() { return state; }
	public void setState(GameState state) { this.state = state; }

	@Persistent(defaultFetchGroup = "true")
	private Collection<String> players = new TreeSet<String>();
	public Collection<String> getPlayers() {
		return new ArrayList<String>(players);
	}
	public void addPlayer(Player player) {
//		if (!state.canAddPlayer()) { throw new IllegalStateException(); }

		for (String p : players) {
			if (p.equals(player.getId())) return;
		}

		players.add(player.getId());
	}
	public void removePlayer(Player player) {
//		if (!state.canAddPlayer()) { throw new IllegalStateException(); }

		players.remove(player.getId());
	}

	@Persistent(defaultFetchGroup = "true")
	private Date start;
	public Date getStart() {
		return start;
	}
	public void setStart(Date start) {
//		if (!state.canStart()) { throw new IllegalStateException(); }
		this.start = start;
	}

	@Persistent(defaultFetchGroup = "true")
	private Date end;
	public Date getEnd() {
		return end;
	}
	public void setEnd(Date end) {
//		if (!state.canEnd()) { throw new IllegalStateException(); }
		this.end = end;
	}

	@Persistent(defaultFetchGroup = "true")
	private String winner;
	public String getWinner() {
		return winner;
	}
	public void setWinner(String winner) {
		this.winner = winner;
	}

	public Game(String id, String name) {
		this.key   = getKey(id);
		this.id    = id;
		this.name  = name;
		this.map   = null;
		this.state = GameState.getInviting(this);
	}
	public Game(String id, String name, AreaMap map) {
		this.key   = getKey(id);
		this.id    = id;
		this.name  = name;
		this.map   = map;
		this.state = GameState.getGenerating(this);
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Game) {
			return equals((Game) obj);
		}

		return false;
	}
	private boolean equals(Game that) {
		if (key == null && that.key == null) return true;

		return key.equals(that.key);
	}

	@Override
	public int hashCode() {
		return key.hashCode();
	}

	@Override
	public String toString() {
		return "[Game "+ map +" "+ players +"]";
	}
}
